package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.mapper.BusAppointmentMapper;
import cn.wolfcode.business.service.IBusAppointmentService;
import cn.wolfcode.business.util.DateUtil;
import cn.wolfcode.business.util.RegexUtils;
import cn.wolfcode.business.util.VehiclePlateNoUtil;
import cn.wolfcode.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 汽车预约服务实现类
 * 实现了 IBusAppointmentService 接口中定义的所有方法
 * 包含具体的业务逻辑和数据验证
 */
@Service  // 标记这是一个Spring服务类
public class BusAppointmentServiceImpl implements IBusAppointmentService {
    
    // 注入数据访问层对象，用于操作数据库
    @Autowired
    private BusAppointmentMapper busAppointmentMapper;
    /**
     * 查询预约信息列表
     * 根据条件从数据库中查询预约记录
     *
     * @param busAppointment 查询条件对象
     * @return 预约信息列表
     */
    @Override
    public List<BusAppointment> selectBusAppointmentList(BusAppointment busAppointment) {
        // 直接调用数据访问层方法查询数据库
        return busAppointmentMapper.selectBusAppointmentList(busAppointment);
    }

    /**
     * 根据ID查询单个预约信息
     * 用于获取预约详情
     *
     * @param id 预约ID
     * @return 预约信息对象
     */
    @Override
    public BusAppointment selectBusAppointmentById(Long id) {
        // 调用数据访问层方法根据ID查询
        return busAppointmentMapper.selectBusAppointmentById(id);
    }

    /**
     * 新增预约信息
     * 客户提交新预约时的处理逻辑，包含严格的数据验证
     *
     * @param busAppointment 预约信息对象
     * @return 操作结果：1表示成功，0表示失败
     */
    @Override
    public int insertBusAppointment(BusAppointment busAppointment) {
        // 1. 基本参数验证 - 确保传入的对象不为空
        if (busAppointment == null) {
            throw new RuntimeException("参数错误");
        }
        
        // 2. 必填字段验证 - 检查所有必要的信息是否都填写了
        if (busAppointment.getCustomerName() == null || busAppointment.getCustomerPhone() == null ||
            busAppointment.getAppointmentTime() == null || busAppointment.getLicensePlate() == null ||
             busAppointment.getCarSeries() == null || busAppointment.getServiceType() == null) {
            throw new RuntimeException("非法参数");
        }

        // 3. 车牌号格式验证 - 使用工具类检查车牌号是否符合规范
        if(VehiclePlateNoUtil.getVehiclePlateNo(busAppointment.getLicensePlate()) == null) {
            throw new RuntimeException("车牌号格式错误");
        }

        // 4. 手机号格式验证 - 使用正则表达式检查手机号格式
        if(!RegexUtils.isPhoneLegal(busAppointment.getCustomerPhone())) {
            throw new RuntimeException("手机号码格式错误");
        }
        
        // 5. 预约时间验证 - 预约时间不能早于当前时间
        Date currentTimePlus1Min = DateUtil.changeDate(new Date(), Calendar.MINUTE, 1);
        if(busAppointment.getAppointmentTime().before(currentTimePlus1Min)) {
            throw new RuntimeException("预约时间不能早于当前时间");
        }
        
        // 6. 设置默认值 - 新预约的状态设为"预约中"，记录创建时间
        busAppointment.setStatus(BusAppointment.STATUS_BOOKING);
        busAppointment.setCreateTime(DateUtils.getNowDate());
        
        // 7. 调用数据访问层保存到数据库
        return busAppointmentMapper.insertBusAppointment(busAppointment);
    }

    /**
     * 修改预约信息
     * 只有状态为"预约中"的记录才能被修改
     *
     * @param busAppointment 包含修改信息的对象
     * @return 操作结果：1表示成功，0表示失败
     */
    @Override
    public int updateBusAppointment(BusAppointment busAppointment) {
        // 1. 基本参数验证
        if(busAppointment == null) {
            throw new RuntimeException("参数错误");
        }
        
        // 2. 手机号格式验证
        if(!RegexUtils.isPhoneLegal(busAppointment.getCustomerPhone())) {
            throw new RuntimeException("手机号码格式错误");
        }
        
        // 3. 车牌号格式验证
        if(VehiclePlateNoUtil.getVehiclePlateNo(busAppointment.getLicensePlate()) == null) {
            throw new RuntimeException("车牌号格式错误");
        }
        
        // 4. 预约时间验证 - 不能早于当前时间
        Date currentTimePlus1Min = DateUtil.changeDate(new Date(), Calendar.MINUTE, 1);
        if(busAppointment.getAppointmentTime().before(currentTimePlus1Min)) {
            throw new RuntimeException("预约时间不能早于当前时间");
        }
        
        // 5. 查询原始数据进行状态验证
        BusAppointment originalRecord = this.selectBusAppointmentById(busAppointment.getId());
        if(originalRecord == null) {
            throw new RuntimeException("参数错误");
        }
        
        // 6. 防止恶意修改状态 - 前端传来的状态必须与数据库中的一致
        if(!busAppointment.getStatus().equals(originalRecord.getStatus())) {
            throw new RuntimeException("状态不允许修改");
        }
        
        // 7. 只有"预约中"状态的记录才能修改
        if(!BusAppointment.STATUS_BOOKING.equals(originalRecord.getStatus())) {
            throw new RuntimeException("状态必须是预约中才可以编辑操作");
        }
        
        // 8. 调用数据访问层更新数据库
        return busAppointmentMapper.updateBusAppointment(busAppointment);
    }

    /**
     * 批量删除预约信息
     * 管理员可以同时删除多个预约记录
     *
     * @param ids 要删除的预约ID数组
     * @return 成功删除的记录数量
     */
    @Override
    public int deleteBusAppointmentByIds(Long[] ids) {
        // 直接调用数据访问层进行批量删除
        return busAppointmentMapper.deleteBusAppointmentByIds(ids);
    }

    /**
     * 取消预约
     * 客户或管理员可以取消状态为"预约中"的记录
     * 
     * @param id 要取消的预约ID
     * @return 操作结果：1表示成功，0表示失败
     */
    @Override
    public int cancel(Long id) {
        // 1. 参数验证 - 确保ID不为空
        if(id == null) {
            throw new RuntimeException("参数错误");
        }
        
        // 2. 查询预约记录是否存在
        BusAppointment busAppointment = this.selectBusAppointmentById(id);
        if(busAppointment == null) {
            throw new RuntimeException("非法参数");
        }
        
        // 3. 状态验证 - 只有"预约中"的记录才能取消
        if(!BusAppointment.STATUS_BOOKING.equals(busAppointment.getStatus())) {
            throw new RuntimeException("状态必须是预约中的记录才能进行取消操作");
        }
        
        // 4. 更新状态为"用户取消"
        return busAppointmentMapper.changeStatusById(BusAppointment.STATUS_USER_CANCELLED, id);
    }

    /**
     * 客户到店操作
     * 当客户实际到达店铺时调用，更新状态和到店时间
     * 
     * @param id 预约ID
     * @return 操作结果：1表示成功，0表示失败
     */
    @Override
    public int Arrival(Long id) {
        // 1. 参数验证 - 确保ID不为空
        if(id == null) {
            throw new RuntimeException("参数错误");
        }
        
        // 2. 查询预约记录是否存在
        BusAppointment busAppointment = this.selectBusAppointmentById(id);
        if(busAppointment == null) {
            throw new RuntimeException("参数错误");
        }
        
        // 3. 状态验证 - 只有"预约中"的记录才能标记为到店
        if(!BusAppointment.STATUS_BOOKING.equals(busAppointment.getStatus())) {
            throw new RuntimeException("状态必须是预约中才可以到店");
        }
        
        // 4. 同时更新状态为"已到店"和记录实际到店时间
        return busAppointmentMapper.changeStatusAndArrivalTimeById(new Date(), BusAppointment.STATUS_ARRIVED, id);
    }

    /**
     * 修改预约单状态
     * 用于业务流程中的状态流转（如结算完成、支付完成等）
     * 
     * @param appointmentId 预约ID
     * @param statusPaid 新的状态值
     */
    @Override
    public void updateStatus(Long appointmentId, Integer statusPaid) {
        // 直接调用数据访问层更新状态
        busAppointmentMapper.changeStatusById(statusPaid, appointmentId);
    }


}
